#include "Join.h"


void mensajeError(int error)
{
    switch (error){
        case 1:
            fprintf(stderr,"ERROR: Clave repetida en el segundo archivo.\n");
            break;
        case 2:
			fprintf(stderr,"ERROR: Clave faltante en el segundo archivo.\n");
			break;
        case 3:
			fprintf(stderr,"ERROR: El segundo archivo esta desordenado.\n");
			break;
    }
}


void leerTeclado(char * arch, int opcion)
{
	FILE * archivoTeclado;

	archivoTeclado = stdin;

	procesarArchivos(arch,"stdin",opcion);

}



void procesarArchivos(char * arch1, char * arch2, int opcion)
{
	FILE * archivo1 = fopen(arch1,"r");
	FILE * archivo2;
	FILE * archDestino = fopen("Destino.txt","w");

	char buffer1[1024];
	//fgets(buffer1,100,archivo1);
	int error = 0;
	int stop = 0;

	archivo2 = procesarTexto(arch2);

	fseek(archivo2,0,SEEK_SET);

	if (estaDesordenado(archivo2,opcion))
	{
		mensajeError(3);
		error = 1;
	}

	while((!error)&&(!feof(archivo1)) && (!stop))
	{
		int seguir = 1;
		int sePaso = 0;
		int resultado = 0;
		int escribio = 0;

		buffer1[0] = '\0';
		fgets(buffer1,1024,archivo1);

		int longBuffer1 = strlen(buffer1);

		if(longBuffer1 > 1)
		{

				Linea linea1 = procesarLinea(buffer1);

				fseek(archivo2,0,SEEK_SET);

				char buffer2[1024];
				fgets(buffer2,1024,archivo2);

				Linea  linea2Actual = procesarLinea(buffer2);
				Linea  linea2Siguiente;


				while(!feof(archivo2) && seguir && !sePaso)
				{
					seguir = 0;

					char buffer2Sig[1024];
					//memset(buffer2Sig, 0, 1024);

					buffer2Sig[0] = '\0';
					fgets(buffer2Sig,1024,archivo2);

					int longSiguiente = strlen(buffer2Sig);

					procesarCaracteresBuffer(buffer2Sig);

					linea2Siguiente = procesarLinea(buffer2Sig);

					resultado = compare(opcion,linea1.clave,linea2Actual.clave);

					if(longSiguiente > 1)
					{

						if(compare(opcion,linea2Siguiente.clave,linea2Actual.clave) == 0)
						{
							mensajeError(1);
							error = 1;
						}
						else
						{
							seguir = procesarResultado(linea1.clave,linea2Actual.clave,linea1.valor,linea2Actual.valor,archDestino,resultado,&escribio);

							if(!seguir && !escribio)
							{
								mensajeError(2);
								error = 1;
							}
						}

						if (linea2Siguiente.clave != NULL){
							strcpy(linea2Actual.clave, linea2Siguiente.clave);
						}
						if (linea2Siguiente.valor != NULL){
							strcpy(linea2Actual.valor, linea2Siguiente.valor);
						}
					}
					else
					{
						sePaso = 1;
						procesarResultado(linea1.clave,linea2Actual.clave,linea1.valor,linea2Actual.valor,archDestino,resultado,&escribio);

					}
				}


				if(seguir)
				{
					resultado = compare(opcion,linea1.clave,linea2Actual.clave);
					procesarResultado(linea1.clave,linea2Actual.clave,linea1.valor,linea2Actual.valor,archDestino,resultado,&escribio);
					if(!escribio)
					{
						mensajeError(2);
						error = 1;
					}
				}
		}
		else {
			stop = 1;
		}

	}

	fclose(archivo1);
	fclose(archivo2);
	fclose(archDestino);

}

int compare(int caseCompare, char * clave1, char * clave2)
{
	int resultado = 0;

	if(caseCompare == 1)
	{
		resultado = strcasecmp(clave1,clave2);
	}
	else
		resultado= strcmp(clave1,clave2);

	return resultado;
}

int procesarResultado(char * clave1, char * clave2,char * valor1, char * valor2,FILE * archDestino,int resultado, int * escribio)
{
	int seguir = 0;
	char * cadena = NULL;

	cadena = calloc(1024,sizeof(char));


	if(resultado == 0)
	{
		strcat(cadena,clave1);
		strcat(cadena," ");
		strcat(cadena,valor1);
		strcat(cadena," ");
		strcat(cadena,valor2);
		strcat(cadena,"\n");

		fputs(cadena,archDestino);

		*escribio = 1;
	}
	else
		if(resultado > 0)
		{
			seguir = 1;
		}

	free(cadena);

	return seguir;
}


FILE * procesarTexto(char * archivo)
{
	FILE * archivoStdin;
	FILE * archivoTexto;

	if (!strcmp(archivo,"stdin"))
	{
		archivoStdin= stdin;

		archivoTexto = 	fopen("Archstdin.txt","w");

		char buffer[1024];
		int caracterCero = 0;

		fgets(buffer,1024,archivoStdin);

		while(!feof(archivoStdin) && !caracterCero)
		{
			Linea linea = procesarLinea(buffer);

			if ((strcmp (linea.clave,"\n")!= 0))
			{
				char * cadena;

				cadena = "\0";
				cadena = calloc(1024,sizeof(char));

				strcat(cadena,linea.clave);
				strcat(cadena," ");
				strcat(cadena,linea.valor);
				strcat(cadena,"\n");
				fputs(cadena,archivoTexto);

				free(cadena);

				fgets(buffer,1024,archivoStdin);

			}
			else
				caracterCero = 1;
		}

		fclose(archivoTexto);
		archivoTexto = fopen("Archstdin.txt","r");

	}
	else
		archivoTexto = fopen(archivo, "r");

	return archivoTexto;
}

Linea procesarLinea(char * linea)
{
	Linea  lineaBis;

	char * ptrToken;
	ptrToken = strtok(linea," ");

	lineaBis.clave = ptrToken;

	ptrToken = strtok(NULL,"\n");

	lineaBis.valor = ptrToken;

	return lineaBis;
}

void imprimirUso()
{
	printf("$ tp0 -h \n");
	printf("Usage: join [OPTION]... FILE1 FILE2\n");
	printf("For each pair of input lines with identical join fields, write a line to\n");
	printf("standard output. The default join field is the first, delimited\n");
	printf("by whitespace. When FILE1 or FILE2 (not both) is -, read standard input.\n");
	printf("\n");
	printf("-i, --ignore-case  ignore differences in case when comparing fields.\n");
	printf("-h, --help         display this help and exit.\n");
	printf("-v, --version      output version information and exit.\n");
	printf("\n");
	printf("Important: FILE1 and FILE2 must be sorted on the join fields.\n");
	printf("E.g., use ‘sort -k 1b,1’ if ‘join’ has no options.\n");
	printf("Note, comparisons honor the rules specified by ‘LC_COLLATE’.\n");
	printf("If the input is not sorted and some lines cannot be joined,a\n");
	printf("warning message will be given.\n");

}

void imprimirVersion()
{

	printf("Version TP0\n");
}

void procesarCaracteresBuffer(char * buffer)
{
	int longLinea = strlen(buffer);

	if(buffer[longLinea-1] =='\n')
		buffer[(longLinea-1)] = '\0';
}

int estaDesordenado(FILE * archivo, int opcion)
{
	char buffer[1024];
	int desordenado = 0;
	int caracterCero = 0;
	int stop = 0;

	fgets(buffer,1024,archivo);

	Linea  linea = procesarLinea(buffer);
	Linea  lineaSiguiente;


	while(!feof(archivo) && !desordenado && !caracterCero && !stop)
	{
		char bufferSig[1024];
		fgets(bufferSig,1024,archivo);

		int longBuffer = strlen(bufferSig);

		if(longBuffer > 1)
		{
			lineaSiguiente = procesarLinea(bufferSig);


			if ((strcmp (lineaSiguiente.clave,"\n")!= 0))
			{
				if (compare(opcion, linea.clave ,lineaSiguiente.clave) > 0 )
					desordenado = 1;

				if (lineaSiguiente.clave != NULL){
					strcpy(linea.clave, lineaSiguiente.clave);
				}
			}
			else
				caracterCero = 1;
		}
		else
			stop = 1;
	}

	return desordenado;
}




